﻿using System;
using System.Collections.Generic;
using System.Net;
namespace SGLib.Net
{
    public class NetClient
    {
        private Action<IPackage> mHandlerFunc;
        ClientSession mSession;
        ICodec mCodec;
        public ICodec Codec { get { return mCodec; } }
        Queue<IPackage> RecvMessageQueue = new Queue<IPackage>();
        //Event
        public event Action<string> NetErrorEvent;
        public event EventHandler Connected;

        public NetClient(ICodec codec,Action<IPackage> handlerFunc)
        { 
            this.mCodec = codec;
            this.mHandlerFunc = handlerFunc;
        }

        public void ConnectAsync(EndPoint remoteEndPoint)
        {
            this.mSession = new ClientSession(this);
            this.mSession.DataReceived += OnSessionDataReceived;
            this.mSession.Connected += OnSessionConnected;
            this.mSession.NetErrorEvent += OnNetErrorEvent;
            this.mSession.Connect(remoteEndPoint);
        }

        private void OnNetErrorEvent(string errorMsg)
        {
            if (NetErrorEvent != null)
            {
                NetErrorEvent(errorMsg);
            }
        }

        private void OnSessionConnected(object sender, EventArgs e)
        {
            if (this.Connected != null)
            {
                this.Connected(this, EventArgs.Empty);
            }
        }

        private void OnSessionDataReceived(object sender, DataEventArgs e)
        {

            object decodeData = this.mCodec.Decode(e.Data, e.Offset,e.Length);
            RecvMessageQueue.Enqueue((IPackage)decodeData);
        }
        public void Send(params object[] data)
        {
            if (mSession != null)
            {
                byte[] codeData = this.Codec.Code(data);
                mSession.Send(new ArraySegment<byte>(codeData, 0, codeData.Length));
            }
            else
            {
                NetErrorEvent("Session为空不能发送消息");
            }
        }

        public void Close()
        {

            if (this.mSession != null)
            {
                this.mSession.Close();
            }
        }

        public void Update()
        {
            
            while (RecvMessageQueue.Count > 0)
            {
               
                this.mHandlerFunc(RecvMessageQueue.Dequeue());
            }
        }

    }
}
